uniform sampler2D tex;
uniform vec3 posCamera;
uniform vec3 posLight;

varying vec4 posFrag;
varying vec3 normal;

const float kFogIntensity = 0.9;
const float kNoiseIntensity = 0.05;
const float kShininess = 10.0;
const float kAmbient = 0.6;
const float kDiffuse = 0.5;
const float kSpecular = 0.05;
const vec4 lightAmbient = vec4(kAmbient, kAmbient, kAmbient, 1.0);
const vec4 lightDiffuse = vec4(kDiffuse, kDiffuse, kDiffuse, 1.0);
const vec4 lightSpec = vec4(kSpecular, kSpecular, kSpecular, 1.0);

float randomf(vec3 vector) { // in [0.0, 1.0]
	return fract(sin(dot(vector.xyz, vec3(12.9898, 78.233, 18.78765))) * 43758.5453);
}

float saturatef(float val) {
	return clamp(val, 0.0, 1.0);
}

void saturatev(vec4 vector) {
	vector.r = saturatef(vector.r);
	vector.g = saturatef(vector.g);
	vector.b = saturatef(vector.b);
	vector.a = saturatef(vector.a);
}

void main() { // MUST BE LAST METHOD ------------------
	vec4 texel = texture2D(tex, gl_TexCoord[0].st);
	float dist = distance(posCamera, posFrag.xyz) * 0.01; // in [0.0, ~1.0]
	float sqrt_dist = sqrt(dist);
	//float fogmod = saturatef((1.0 - sqrt_dist) * kFogIntensity);
	float noisemod = 1.0 - randomf(posFrag.xyz) * kNoiseIntensity; // in [0.9, 1.0]
	//texel.rgb *= fogmod;
	texel.rgb *= noisemod;
	
	vec4 lightDir = normalize(vec4(posLight, 1.0) - posFrag);
	vec4 blinnphong = 
		lightAmbient
		+ lightDiffuse * saturatef(dot(normal, -lightDir.xyz))
		+ lightSpec * saturatef(pow(dot(normalize(lightDir.xyz + posFrag.xyz - posCamera), normal), kShininess));
	//blinnphong.rgb *= (1.0 - 1.0 * sqrt_dist);
	blinnphong.rgb *= (1.0 - 1.0 * dist);
	saturatev(blinnphong);
	gl_FragColor = blinnphong * texel;
}
